import jqdatasdk as jq
from datetime import timedelta,datetime
from typing import List
# 导入交易所与交易级别常量
from vnpy.trader.constant import Exchange,Interval
# 导入数据接口抽象API类
from vnpy.trader.mddata.dataapi import MdDataApi
# 导入K线数据，历史请求数据
from vnpy.trader.object import BarData,HistoryRequest
# 导入系统设置
from vnpy.trader.setting import SETTINGS

INTERVAL_VT2JQ = {
    Interval.MINUTE:"1m",
    Interval.HOUR:"60m",
    Interval.DAILY:"1d"
}

INTERVAL_ADJUSTMENT_MAP_JQ = {
    Interval.MINUTE:timedelta(minutes=1),
    Interval.HOUR:timedelta(hours=1),
    Interval.DAILY:timedelta(),
}

class JqdataClient(MdDataApi):
    """
    聚宽JQData客户端封装类
    """
    def __init__(self):
        """"""
        self.username = SETTINGS['jqdata.username']
        self.password = SETTINGS['jqdata.password']
        self.inited = False


    def init(self,username="",password=""):
        if self.inited:
            return True
        if username and password:
            self.username = username
            self.password = password
        if not self.username or not self.password:
            return False

        try:
            jq.auth(self.username,self.password)
        except Exception as ex:
            print("jq auth fail:"+repr(ex))
            return False
        self.inited = True
        return True


    def to_jq_symbol(self,symbol:str,exchange:Exchange):
        """
        """
        # print(exchange);
        # print(symbol);
        # sys.exit()
        if exchange in [Exchange.SSE,Exchange.SZSE]:
            # 上海证券交易所
            if exchange == Exchange.SSE:
                jq_symbol = f"{symbol}.XSHG"
            else:
                jq_symbol = f"{symbol}.XSHE"
        elif exchange == Exchange.SHFE:
            jq_symbol = f"{symbol}.XSGE" #上期所
        elif exchange == Exchange.CFFEX:
            jq_symbol = f"{symbol}.CCFX" #中金所
        elif exchange == Exchange.DCE:
            jq_symbol = f"{symbol}.XDCE" #大商所
        elif exchange == Exchange.INE:
            jq_symbol = f"{symbol}.XINE" #上海国际能源期货交易所
        elif exchange == Exchange.CZCE:
            for count,word in enumerate(symbol):
                if word.isdigit():
                    break

            time_str = symbol[count:]
            # print(time_str)
            # print(symbol)
            # sys.exit()
            if time_str in ["88","888","99","8888"]:
                return symbol
            product = symbol[:count]
            year = symbol[count]
            month = symbol[count+1:]
            if year == "9":
                year = "1"+year
            else:
                year = "2"+year

            jq_symbol = f"{product}{year}{month}.XZCE"
        return jq_symbol.upper()


    def query_history(self,req:HistoryRequest):
        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end
        jq_symbol  = self.to_jq_symbol(symbol,exchange)
        jq_interval = INTERVAL_VT2JQ.get(interval)

        if not jq_interval:
            return None
        # 用来调整从收盘价到开盘价的时间戳
        adjustment = INTERVAL_ADJUSTMENT_MAP_JQ.get(interval)

        now = datetime.now()
        if end >=now:
            end =now
        elif end.year == now.year and end.month == now.month and end.day == now.day:
            end = now

        df = jq.get_price(jq_symbol,
                          frequency=jq_interval,
                          fields=['open','high','low','close','volume'],
                          start_date=start,
                          end_date=end,
                          skip_paused=True
        )

        data:list[BarData] = []
        if df is not None:
            for ix,row in df.iterrows():
                bar = BarData(
                    symbol = symbol,
                    exchange = exchange,
                    interval = interval,
                    datetime = row.name.to_pydatetime()-adjustment,
                    open_price=row['open'],
                    high_price=row['high'],
                    low_price=row['low'],
                    close_price=row['close'],
                    volume=row['volume'],
                    gateway_name="JQ"
                )
                data.append(bar)
        return data


jqdata_client = JqdataClient()
